package Gui;

//Test
import java.awt.Toolkit;
import java.awt.event.*;
import java.awt.Event;
import javax.swing.*;
import java.awt.Point;
import java.awt.*;
import java.util.ArrayList;
import javax.swing.border.*;
import javax.swing.event.MouseInputListener;
import Logic.Ball;
import Logic.ballLabel;
import Logic.CollisionDetection;
import Logic.timerClass;
import java.util.Timer;
import java.util.TimerTask;

public class frontend_main extends JFrame implements MouseMotionListener,
MouseListener {

	private JFrame jFrame = null; // @jve:decl-index=0:visual-constraint="10,10"
	private JPanel jContentPane = null;
	private JMenuBar jJMenuBar = null;
	private JMenu fileMenu = null;
	private JMenu editMenu = null;
	private JMenu helpMenu = null;
	private JMenuItem exitMenuItem = null;
	private JMenuItem aboutMenuItem = null;
	private JMenuItem cutMenuItem = null;
	private JMenuItem copyMenuItem = null;
	private JMenuItem pasteMenuItem = null;
	private JMenuItem saveMenuItem = null;
	private JFrame consoleFrame = null; // @jve:decl-index=0:visual-constraint="504,10"
	private JPanel aboutContentPane = null;
	public static JPanel ballPanel = null;
	private JButton add00 = null;
	private JButton add01 = null;
	private JButton add10 = null;
	private JButton add11 = null;
	// private Graphics2D g2; // @jve:decl-index=0:
	public static ArrayList<Ball> ballList = new ArrayList<Ball>(); // @jve:decl-index=0:
	private JButton clearButton = null;
	public static JTextArea consoleArea = null;
	public static JScrollPane scrollPane = null;
	private JButton showConsoleBtn = null;
	private CollisionDetection detector = new CollisionDetection();
        private timerClass timer;

//	 create a timer
	 private int delay = 1;
//	 protected Timer timer = new Timer();

	/**
	 * This is the constructor method for class frontend_main
	 *
	 */
	public frontend_main() {
		 timer = new timerClass(delay);

	}

//	 private class TimerListener implements ActionListener{
//	 public void actionPerformed(ActionEvent e){
//	 if(ballList.size() != 0){
//		 System.out.println(ballList.get(0).getLabelX());
//
//	 }
//	 }
//	 }

	/**
	 * This method initializes jFrame
	 *
	 * @return javax.swing.JFrame
	 */
	private JFrame getJFrame() {
		if (jFrame == null) {
			jFrame = new JFrame();
			jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			jFrame.setJMenuBar(getJJMenuBar());
			jFrame.setSize(485, 369);
			jFrame.setContentPane(getJContentPane());
			jFrame.setTitle("YingYang Bipolorization");
			JFrame aboutDialog = getConsoleFrame();
			aboutDialog.setVisible(false);
		}
		return jFrame;
	}

	/**
	 * This method initializes jContentPane
	 *
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(null);
			jContentPane.add(getBallPanel(), null);
			jContentPane.add(getAdd00(), null);
			jContentPane.add(getAdd01(), null);
			jContentPane.add(getAdd10(), null);
			jContentPane.add(getAdd11(), null);
			jContentPane.add(getClearButton(), null);
			jContentPane.add(getShowConsoleBtn(), null);
		}
		return jContentPane;
	}

	/**
	 * This method initializes jJMenuBar
	 *
	 * @return javax.swing.JMenuBar
	 */
	private JMenuBar getJJMenuBar() {
		if (jJMenuBar == null) {
			jJMenuBar = new JMenuBar();
			jJMenuBar.add(getFileMenu());
			jJMenuBar.add(getEditMenu());
			jJMenuBar.add(getHelpMenu());
		}
		return jJMenuBar;
	}

	/**
	 * This method initializes jMenu
	 *
	 * @return javax.swing.JMenu
	 */
	private JMenu getFileMenu() {
		if (fileMenu == null) {
			fileMenu = new JMenu();
			fileMenu.setText("File");
			fileMenu.add(getSaveMenuItem());
			fileMenu.add(getExitMenuItem());
		}
		return fileMenu;
	}

	/**
	 * This method initializes jMenu
	 *
	 * @return javax.swing.JMenu
	 */
	private JMenu getEditMenu() {
		if (editMenu == null) {
			editMenu = new JMenu();
			editMenu.setText("Edit");
			editMenu.add(getCutMenuItem());
			editMenu.add(getCopyMenuItem());
			editMenu.add(getPasteMenuItem());
		}
		return editMenu;
	}

	/**
	 * This method initializes jMenu
	 *
	 * @return javax.swing.JMenu
	 */
	private JMenu getHelpMenu() {
		if (helpMenu == null) {
			helpMenu = new JMenu();
			helpMenu.setText("Help");
			helpMenu.add(getAboutMenuItem());
		}
		return helpMenu;
	}

	/**
	 * This method initializes jMenuItem
	 *
	 * @return javax.swing.JMenuItem
	 */
	private JMenuItem getExitMenuItem() {
		if (exitMenuItem == null) {
			exitMenuItem = new JMenuItem();
			exitMenuItem.setText("Exit");
			exitMenuItem.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					System.exit(0);
				}
			});
		}
		return exitMenuItem;
	}

	/**
	 * This method initializes jMenuItem
	 *
	 * @return javax.swing.JMenuItem
	 */
	private JMenuItem getAboutMenuItem() {
		if (aboutMenuItem == null) {
			aboutMenuItem = new JMenuItem();
			aboutMenuItem.setText("About");
			aboutMenuItem.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					// JFrame aboutDialog = getAboutDialog();
					// aboutDialog.pack();
					Point loc = getJFrame().getLocation();
					loc.translate(331, 260);
					consoleFrame.setLocation(loc);
					consoleFrame.setVisible(true);
				}
			});
		}
		return aboutMenuItem;
	}

	/**
	 * This method initializes consoleFrame
	 *
	 * @return javax.swing.JDialog
	 */
	private JFrame getConsoleFrame() {
		if (consoleFrame == null) {
			consoleFrame = new JFrame();
			consoleFrame.setTitle("Console");
			consoleFrame.setSize(331, 260);


			consoleFrame.setContentPane(getAboutContentPane());

		}
		return consoleFrame;
	}

	/**
	 * This method initializes aboutContentPane
	 *
	 * @return javax.swing.JPanel
	 */
	private JPanel getAboutContentPane() {
		if (aboutContentPane == null) {
			aboutContentPane = new JPanel();
			aboutContentPane.setLayout(null);
			aboutContentPane.add(getScrollPane(), null);
		}
		return aboutContentPane;
	}

	/**
	 * This method initializes jMenuItem
	 *
	 * @return javax.swing.JMenuItem
	 */
	private JMenuItem getCutMenuItem() {
		if (cutMenuItem == null) {
			cutMenuItem = new JMenuItem();
			cutMenuItem.setText("Cut");
			cutMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,
					Event.CTRL_MASK, true));
		}
		return cutMenuItem;
	}

	/**
	 * This method initializes jMenuItem
	 *
	 * @return javax.swing.JMenuItem
	 */
	private JMenuItem getCopyMenuItem() {
		if (copyMenuItem == null) {
			copyMenuItem = new JMenuItem();
			copyMenuItem.setText("Copy");
			copyMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,
					Event.CTRL_MASK, true));
		}
		return copyMenuItem;
	}

	/**
	 * This method initializes jMenuItem
	 *
	 * @return javax.swing.JMenuItem
	 */
	private JMenuItem getPasteMenuItem() {
		if (pasteMenuItem == null) {
			pasteMenuItem = new JMenuItem();
			pasteMenuItem.setText("Paste");
			pasteMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V,
					Event.CTRL_MASK, true));
		}
		return pasteMenuItem;
	}

	/**
	 * This method initializes jMenuItem
	 *
	 * @return javax.swing.JMenuItem
	 */
	private JMenuItem getSaveMenuItem() {
		if (saveMenuItem == null) {
			saveMenuItem = new JMenuItem();
			saveMenuItem.setText("Save");
			saveMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
					Event.CTRL_MASK, true));
		}
		return saveMenuItem;
	}

	/**
	 * This method initializes ballPanel
	 *
	 * @return javax.swing.JPanel
	 */
	private JPanel getBallPanel() {
		if (ballPanel == null) {
			ballPanel = new JPanel();
			// ballPanel = new CircleDraw();
			ballPanel.setLayout(null);
			ballPanel.setBounds(new Rectangle(6, 50, 458, 252));
			ballPanel.setBackground(Color.white);
			ballPanel.setBorder(BorderFactory
					.createEtchedBorder(EtchedBorder.LOWERED));
			ballPanel.setForeground(Color.white);
			ballPanel.addMouseMotionListener(this);
			ballPanel.addMouseListener(this);

		}
		return ballPanel;
	}

	/**
	 * This method initializes add00
	 *
	 * @return javax.swing.JButton
	 */
	private JButton getAdd00() {
		if (add00 == null) {
			add00 = new JButton("Add (0,0) Blue");
			add00.setBounds(new Rectangle(8, 6, 150, 18));
			add00.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
                                        if(ballList.size() <= 3)
                                        {
                                            String type = "00";
                                            Ball ball = new Ball(type,0,0);
                                            Ball ball2 = new Ball(type, ball,0,0);
                                            ballList.add(ball);
                                            ballList.add(ball2);
                                            ballPanel.repaint();
                                            getLevels();
                                        }
                                        else
                                            JOptionPane.showMessageDialog(null, "You cannot have over 4 balls.");
				}
			});
		}

		return add00;
	}

	/**
	 * This method initializes add01
	 *
	 * @return javax.swing.JButton
	 */
	private JButton getAdd01() {
		if (add01 == null) {
			add01 = new JButton("Add (0,+1) Yellow");
			add01.setBounds(new Rectangle(160, 6, 150, 18));
			add01.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					if(ballList.size() <= 3)
                                        {
                                            String type = "01";
                                            Ball ball = new Ball(type,0,1);
                                            Ball ball2 = new Ball(type, ball,0,1);
                                            ballList.add(ball);
                                            ballList.add(ball2);
                                            ballPanel.repaint();
                                            getLevels();
                                        }
                                        else
                                            JOptionPane.showMessageDialog(null, "You cannot have over 4 balls.");
				}
			});

		}

		return add01;
	}

	/**
	 * This method initializes add10
	 *
	 * @return javax.swing.JButton
	 */
	private JButton getAdd10() {
		if (add10 == null) {
			add10 = new JButton("Add (-1,0) Red");
			add10.setBounds(new Rectangle(8, 27, 150, 18));
			add10.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					if(ballList.size() <= 3)
                                        {
                                            String type = "-10";
                                            Ball ball = new Ball(type,1,0);
                                            Ball ball2 = new Ball(type, ball,1,0);
                                            ballList.add(ball);
                                            ballList.add(ball2);
                                            ballPanel.repaint();
                                            getLevels();
                                        }
                                        else
                                            JOptionPane.showMessageDialog(null, "You cannot have over 4 balls.");
				}
			});
		}
		return add10;
	}

	/**
	 * This method initializes add11
	 *
	 * @return javax.swing.JButton
	 */
	private JButton getAdd11() {
		if (add11 == null) {
			add11 = new JButton();
			add11.setBounds(new Rectangle(160, 27, 150, 18));
			add11.setText("Add (-1,+1) Green");
			add11.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					if(ballList.size() <= 3)
                                        {
                                            String type = "-11";
                                            Ball ball = new Ball(type,1,1);
                                            Ball ball2 = new Ball(type, ball,1,1);
                                            ballList.add(ball);
                                            ballList.add(ball2);
                                            ballPanel.repaint();
                                            getLevels();
                                        }
                                        else
                                            JOptionPane.showMessageDialog(null, "You cannot have over 4 balls.");
				}
			});
		}
		return add11;
	}

	// public void paint (Graphics g) {
	// g2 = (Graphics2D) g;
	// }

	/**
	 * This method initializes clearButton
	 *
	 * @return javax.swing.JButton
	 */
	private JButton getClearButton() {
		if (clearButton == null) {
			clearButton = new JButton();
			clearButton.setBounds(new Rectangle(337, 6, 125, 18));
			clearButton.setText("Clear Balls");
			clearButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					ballList.clear();
					ballPanel.removeAll();
					ballPanel.repaint();
					consoleArea.append("Cleared Balls\n");
				}
			});
		}
		return clearButton;
	}

	/**
	 * This method initializes consoleArea
	 *
	 * @return javax.swing.JTextArea
	 */
	private JTextArea getConsoleArea() {

		if (consoleArea == null) {
			consoleArea = new JTextArea();
//			consoleArea.setBounds(new Rectangle(7, 4, 303, 215));
//			consoleArea.setBorder(BorderFactory
//					.createEtchedBorder(EtchedBorder.LOWERED));
		}
		return consoleArea;
	}

	private JScrollPane getScrollPane(){
		if(scrollPane == null){
			scrollPane = new JScrollPane(getConsoleArea());
			scrollPane.setBounds(new Rectangle(7, 4, 303, 215));
			scrollPane.setBorder(BorderFactory
					.createEtchedBorder(EtchedBorder.LOWERED));
		}
		return scrollPane;
	}
	/**
	 * This method initializes showConsoleBtn
	 *
	 * @return javax.swing.JButton
	 */
	private JButton getShowConsoleBtn() {
		if (showConsoleBtn == null) {
			showConsoleBtn = new JButton();
			showConsoleBtn.setBounds(new Rectangle(337, 27, 125, 18));
			showConsoleBtn.setText("Show Console");
			showConsoleBtn
					.addActionListener(new java.awt.event.ActionListener() {
						public void actionPerformed(java.awt.event.ActionEvent e) {
							consoleFrame.setVisible(true);
						}
					});
		}
		return showConsoleBtn;
	}

	/**
	 * detection method : basically cycles through the ballList
	 * and calls the getLevel class
	 */
	//TODO : find a better way to do this
	public void getLevels(){

		if (this.ballList.size() > 1) {

			//reset ball Levels
			resetBalls();


			for (int i = 0; i < this.ballList.size() - 1; i++) {
				for (int j = 0; j < this.ballList.size(); j++) {
					if(i == j){
						j++;
					}
					//set xLevels for each ball
					int xLevel = detector.getXLevel(this.ballList.get(i),
							this.ballList.get(j));
					this.ballList.get(i).setXLevel(xLevel);
					this.ballList.get(j).setXLevel(xLevel);

					//set yLevels for each ball
					int yLevel = detector.getYLevel(this.ballList.get(i),
							this.ballList.get(j));
					this.ballList.get(i).setYLevel(yLevel);
					this.ballList.get(j).setYLevel(yLevel);
				}
			}

			//prints in console ball levels
			for(int i = 0; i < ballList.size(); i ++){
				consoleArea.append("ball " + i + " X level : " +
						this.ballList.get(i).getXLevel() + "\n");
				consoleArea.append("ball " + i + " Y level : " +
						this.ballList.get(i).getYLevel() + "\n");
			}
		}
	}
	/**
	 * method to reset levels on balls, done after a move has occurred
	 * and before when calling the getLevels method
	 */
	public void resetBalls(){

		if(this.ballList.size() > 1){
			for(int i = 0; i < this.ballList.size(); i++){
				this.ballList.get(i).resetXLevel();
				this.ballList.get(i).resetYLevel();
			}
		}

	}

	/**
	 * Sort array by x coord
	 * @param array
	 */
	public void getBallsX(ArrayList<Ball> array){
		boolean next = true;
		for(int k = 1; k < array.size() && next; k++){
			next = false;
			for(int i = 0; i < array.size() - k; i++){
				if(array.get(i).getLabelX() > array.get(i + 1).getLabelX()){
					Ball temp = array.get(i);
					array.set(i, array.get(i + 1));
					array.set(i + 1, temp);

					next = true;
				}
			}
		}
	}

	/**
	 * Launches this application
	 */
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				UIManager.put("swing.boldMetal", Boolean.FALSE);
				frontend_main application = new frontend_main();
				application.getJFrame().setVisible(true);
			}
		});
	}

	@Override
	public void mouseDragged(MouseEvent arg0) {
		// TODO Auto-generated method stub
	}

	@Override
	public void mouseMoved(MouseEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub

	}
//TODO : Make mouse movement reset ball levels
/**
 * Mouse entered is call when moving the JLabal in the JPanel,
 * so everytime it is call, needs to call the resetLevels method.
 */
	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		//System.out.println("Entered");
		getLevels();
//		if(ballList.isEmpty() == false)
//			System.out.println(ballList.get(0).getBallX());
		getBallsX(ballList);
	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub

	}

}
